package org.apereo.cas.configuration.model.support.mfa;

import org.apereo.cas.configuration.support.RequiresModule;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.io.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;

/**
 * Configuration properties class for cas.mfa.
 *
 * @author Dmitriy Kopylenko
 * @since 5.0.0
 */
@RequiresModule(name = "cas-server-core-authentication", automated = true)

@Getter
@Setter
public class MultifactorAuthenticationProperties implements Serializable {

    private static final long serialVersionUID = 7416521468929733907L;

    /**
     * Attribute returned in the final CAS validation payload
     * that indicates the authentication context class satisified
     * in the event of a multifactor authentication attempt.
     * 在最终的CAS验证负载中返回的属性
     * 表示身份验证上下文类已满足
     * 在多因素身份验证尝试的情况下。
     */
    private String authenticationContextAttribute = "authnContextClass";

    /**
     * Defines the global failure mode for the entire deployment.
     * This is meant to be used a shortcut to define the policy globally
     * rather than per application. Applications registered with CAS can still
     * define a failure mode and override the global.
     * *定义整个部署的全局故障模式。
     * *这是用来在全局范围内定义策略的快捷方式
     * *而不是每个应用程序。在CAS注册的应用程序仍然可以
     * *定义故障模式并覆盖全局。
     */
    private String globalFailureMode = "CLOSED";

    /**
     * MFA can be triggered for a specific authentication request,
     * provided the  request  contains a session/request attribute that indicates the required MFA authentication flow.
     * The attribute name is configurable, but its value must match the authentication provider id of an available MFA provider.
     *可以针对特定的身份验证请求触发MFA，
      前提是请求包含一个session/request属性，该属性指示所需的MFA身份验证流。
      属性名是可配置的，但其值必须与可用的MFA提供程序的身份验证提供程序id匹配。
     */
    private String sessionAttribute = "authn_method";

    /**
     * MFA can be triggered for a specific authentication request,
     * provided the initial request to the CAS /login endpoint contains a request header that indicates the required MFA authentication flow.
     * The header name is configurable, but its value must match the authentication provider id of an available MFA provider.
     可以针对特定的身份验证请求触发MFA，
     前提是对CAS/login端点的初始请求包含指示所需MFA身份验证流的请求头。
     标头名称是可配置的，但其值必须与可用的MFA提供程序的身份验证提供程序id匹配。
     */
    private String requestHeader = "authn_method";

    /**
     * MFA can be triggered for a specific authentication request,
     * provided the initial request to the CAS /login endpoint contains a parameter that indicates the required MFA authentication flow.
     * The parameter name is configurable, but its value must match the authentication provider id of an available MFA provider.
     * 可以针对特定的身份验证请求触发MFA，
     * 前提是对CAS/login端点的初始请求包含指示所需MFA身份验证流的参数。
       参数名是可配置的，但其值必须与可用的MFA提供程序的身份验证提供程序id匹配。
     */
    private String requestParameter = "authn_method";

    /**
     * MFA can be triggered based on the results of a remote REST endpoint of your design.
     * If the endpoint is configured, CAS shall issue a POST, providing the principal and the service url.
     * The body of the response in the event of a successful 200 status code is
     * expected to be the MFA provider id which CAS should activate.
     *可以根据设计的远程REST端点的结果触发MFA。
     *如果配置了端点，CAS将发出POST，提供主体和服务url。
     *成功的200状态代码的响应主体是
     *应为CAS应激活的MFA提供程序id。
     */
    private String restEndpoint;

    /**
     * MFA can be triggered based on the results of a groovy script of your own design.
     * The outcome of the script should determine the MFA provider id that CAS should attempt to activate.
     * 可以根据自己设计的groovy脚本的结果触发MFA。
     * 脚本的结果应确定CAS应尝试激活的MFA提供程序id。
     */
    private transient Resource groovyScript;

    /**
     * This is a more generic variant of the @{link #globalPrincipalAttributeNameTriggers}.
     * It may be useful in cases where there
     * is more than one provider configured and available in the application runtime and
     * you need to design a strategy to dynamically decide on the provider that should be activated for the request.
     * The decision is handed off to a Predicate implementation that define in a Groovy script whose location is taught to CAS.
     * 这是@{linkŠglobalPrincipalAttributeNameTriggers}的一个更通用的变体。
      它可能在以下情况下有用
      在应用程序运行时中配置了多个提供程序，并且
      您需要设计一种策略来动态地决定应该为请求激活的提供者。
      决定权交给一个谓词实现，该实现在Groovy脚本中定义，该脚本的位置被传授给CAS。
     */
    private transient Resource globalPrincipalAttributePredicate;

    /**
     * MFA can be triggered for all users/subjects carrying a specific attribute that matches one of the conditions below.
     * <ul>
     * <li>Trigger MFA based on a principal attribute(s) whose value(s) matches a regex pattern.
     * Note that this behavior is only applicable if there is only a single MFA provider configured,
     * since that would allow CAS to know what provider to next activate.</li>
     * <li>Trigger MFA based on a principal attribute(s) whose value(s) EXACTLY matches an MFA provider.
     * This option is more relevant if you have more than one provider configured or if you have the flexibility
     * of assigning provider ids to attributes as values.</li>
     * </ul>
     * Needless to say, the attributes need to have been resolved for the principal prior to this step.
     * 对于具有符合以下条件之一的特定属性的所有用户/主题，都可以触发MFA。
     * *<ul>
     * *<li>根据值与regex模式匹配的主属性触发MFA。
     * *请注意，此行为仅适用于仅配置了单个MFA提供程序的情况，
     * *因为这样可以让CAS知道下一步激活哪个提供者</li>
     * *<li>根据值与MFA提供程序完全匹配的主属性触发MFA。
     * *如果配置了多个提供程序或具有灵活性，则此选项更为相关
     * *将提供者id作为值分配给属性</li>
     * *</ul>
     * *不用说，在这一步之前，需要为主体解析属性。
     */
    private String globalPrincipalAttributeNameTriggers;

    /**
     * The regular expression that is cross matches against the principal attribute to determine
     * if the account is qualified for multifactor authentication.
     * 正则表达式与主属性交叉匹配以确定
     * 如果帐户符合多因素身份验证的条件。
     */
    private String globalPrincipalAttributeValueRegex;

    /**
     * MFA can be triggered for all users/subjects whose authentication event/metadata has resolved a specific attribute that
     * matches one of the below conditions:
     * <ul>
     * <li>Trigger MFA based on a authentication attribute(s) whose value(s) matches a regex pattern.
     * Note that this behavior is only applicable if there is only a single MFA provider configured,
     * since that would allow CAS to know what provider to next activate. </li>
     * <li>Trigger MFA based on a authentication attribute(s) whose value(s) EXACTLY matches an MFA provider.
     * This option is more relevant if you have more than one provider configured or if you have the
     * flexibility of assigning provider ids to attributes as values. </li>
     * </ul>
     * Needless to say, the attributes need to have been resolved for the authentication event prior to this step.
     * This trigger is generally useful when the underlying authentication engine signals
     * CAS to perform additional validation of credentials. This signal may be captured by CAS as
     * an attribute that is part of the authentication event metadata which can then trigger
     * additional multifactor authentication events.
     * *对于所有身份验证事件/元数据已解析特定属性的用户/主题，都可以触发MFA
     * *匹配以下条件之一：
     * *<ul>
     * *<li>基于与regex模式匹配的身份验证属性触发MFA。
     * *注意，只有在配置了单个MFA提供程序时，此行为才适用，
     * *因为这将允许CAS知道下一个激活的提供者。</li>
     * *<li>基于与MFA提供程序完全匹配的身份验证属性触发MFA。
     * *如果配置了多个提供程序或您有
     * *将提供程序ID指定给属性作为值的灵活性。</li>
     * *</ul>
     * *不用说，在这一步之前，需要为身份验证事件解析属性。
     * *当底层身份验证引擎信号时，此触发器通常很有用
     * *CAS执行凭据的其他验证。CAS as可以捕获此信号
     * *一个属性，它是身份验证事件元数据的一部分，然后可以触发该属性
     * *其他多因素身份验证事件。
     */
    private String globalAuthenticationAttributeNameTriggers;

    /**
     * The regular expression that is cross matches against the authentication attribute to determine
     * if the account is qualified for multifactor authentication.
     * 与要确定的身份验证属性交叉匹配的正则表达式
     * 如果帐户符合多因素身份验证的条件。
     */
    private String globalAuthenticationAttributeValueRegex;

    /**
     * Content-type that is expected to be specified by non-web clients such as curl, etc in the
     * event that the provider supports variations of non-browser based MFA.
     * 中预期由非web客户端（如curl等）指定的内容类型
     * 提供程序支持非基于浏览器的MFA变体的事件。
     */
    private String contentType = "application/cas";

    /**
     * MFA can be triggered for all applications and users regardless of individual settings.
     * This setting holds the value of an MFA provider that shall be activated for all requests,
     * regardless.
     * 可以为所有应用程序和用户触发MFA，而不考虑各个设置。
     * 此设置保存MFA提供程序的值，该值应为所有请求激活，
     * 不管怎样。
     */
    private String globalProviderId;

    /**
     * MFA can be triggered by Grouper groups to which the authenticated principal is assigned.
     * Groups are collected by CAS and then cross-checked against all available/configured MFA providers.
     * The group’s comparing factor MUST be defined in CAS to activate this behavior and
     * it can be based on the group’s name, display name,
     * etc where a successful match against a provider id shall activate the chosen MFA provider.
     * MFA可以由分配了经过身份验证的主体的Grouper组触发。
     * 组由CA收集，然后与所有可用/配置的MFA提供程序进行交叉检查。
     * 组的比较因子必须在CAS中定义才能激活此行为，并且
     * 它可以基于组的名称、显示名称，
     * 等，如果与提供者id的成功匹配将激活所选的MFA提供者。
     */
    private String grouperGroupField;

    /**
     * In the event that multiple multifactor authentication providers are determined for a multifactor authentication transaction,
     * by default CAS will attempt to sort the collection of providers based on their rank and
     * will pick one with the highest priority. This use case may arise if multiple triggers
     * are defined where each decides on a different multifactor authentication provider, or
     * the same provider instance is configured multiple times with many instances.
     * Provider selection may also be carried out using Groovy scripting strategies more dynamically.
     * The following example should serve as an outline of how to select multifactor providers based on a Groovy script.
     * 如果为多因素身份验证事务确定了多个多因素身份验证提供程序，
     * 默认情况下，CAS将尝试根据提供者的等级和
     * 将选择优先级最高的一个。如果有多个触发器，则可能会出现此用例
     * 在每个人决定不同的多因素身份验证提供程序时定义，或
     * 同一个提供程序实例使用多个实例进行多次配置。
     * 提供者选择也可以使用Groovy脚本策略更动态地执行。
     * 下面的示例应该是如何基于Groovy脚本选择多因素提供者的概要。
     */
    private transient Resource providerSelectorGroovyScript;

    /**
     * Activate and configure a multifactor authentication provider via U2F FIDO.
     * 通过U2F FIDO激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private U2FMultifactorProperties u2f = new U2FMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via Microsoft Azure.
     * 通过Microsoft Azure激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private AzureMultifactorProperties azure = new AzureMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication with the capability to trust and remember devices.
     * 激活和配置具有信任和记住设备功能的多因素身份验证。
     */
    @NestedConfigurationProperty
    private TrustedDevicesMultifactorProperties trusted = new TrustedDevicesMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via YubiKey.
     * 通过YubiKey激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private YubiKeyMultifactorProperties yubikey = new YubiKeyMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via RADIUS.
     * 通过RADIUS激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private RadiusMultifactorProperties radius = new RadiusMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via Google Authenticator.
     * 通过googleauthenticator激活和配置多因素身份验证提供者。
     */
    @NestedConfigurationProperty
    private GAuthMultifactorProperties gauth = new GAuthMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via Duo Security.
     * 通过Duo-Security激活和配置多因素身份验证提供程序。
     */
    private List<DuoSecurityMultifactorProperties> duo = new ArrayList<>();

    /**
     * Activate and configure a multifactor authentication provider via Authy.
     * 通过身份验证激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private AuthyMultifactorProperties authy = new AuthyMultifactorProperties();

    /**
     * Activate and configure a multifactor authentication provider via Swivel.
     * 通过Swivel激活和配置多因素身份验证提供程序。
     */
    @NestedConfigurationProperty
    private SwivelMultifactorProperties swivel = new SwivelMultifactorProperties();
}
